package org.mtmi.io;

import java.util.Vector;

import net.n3.nanoxml.IXMLElement;

import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;

/**
 * Some useful method to reader data from XML over NanoXML stuff...
 */
public class XMLReader 
{

	/** @return the element 'tagname' child of element, if it's single. Otherwise, throw ReaderError if mandatory, or null if optional */
	public IXMLElement getElement( IXMLElement element, String tagname, boolean mandatory ) throws ReaderError
	{
		Vector<?> children = element.getChildrenNamed( tagname );
		if( children!=null && children.size()==1 ) { 
			Object n =children.get( 0 );
			if( n instanceof IXMLElement ) return (IXMLElement)n;
		}
		if( mandatory ) {
			throw new ReaderError("missing '"+tagname+"' in element '"+element.getName()+"'");
		} else {
			return null;
		}
	}
	
	/** @return the value of integer attribute in element, otherwise throw {@link ReaderError} */
	public int getAttrInt( IXMLElement element, String attr_name ) throws ReaderError
	{
		String v = element.getAttribute( attr_name, null );
		if( v!=null )  {
			try {
				int value = Integer.parseInt( v );
				return value;
			} catch( NumberFormatException x ) {
				throw new ReaderError("Attribute '"+attr_name+"' of element '"+element.getName()+"' is not an integer");
			}
		} else {
			throw new ReaderError("Missing integer attribute '"+attr_name+"' in element '"+element.getName()+"'");			
		}
	}
	
	/** @return the value of float attribute in element, otherwise throw {@link ReaderError} */
	public float getAttrFloat( IXMLElement element, String attr_name ) throws ReaderError
	{
		String v = element.getAttribute( attr_name, null );
		if( v!=null )  {
			try {
				float value = Float.parseFloat( v );
				return value;
			} catch( NumberFormatException x ) {
				throw new ReaderError("Attribute '"+attr_name+"' of element '"+element.getName()+"' is not a float");
			}
		} else {
			throw new ReaderError("Missing float attribute '"+attr_name+"' in element '"+element.getName()+"'");			
		}
	}
	
	/** @return the value of boolean attribute in element, otherwise throw {@link ReaderError} */
	public boolean getAttrBoolean( IXMLElement element, String attr_name ) throws ReaderError
	{
		String v = element.getAttribute( attr_name, null );
		if( v!=null ) {
			if( Boolean.TRUE.toString().equals( v ) ) return true;
			if( Boolean.FALSE.toString().equals( v ) ) return false;
			throw new ReaderError("Attribute '"+attr_name+"' of element '"+element.getName()+"' is not a boolean");
		} else {
			throw new ReaderError("Missing boolean attribute '"+attr_name+"' in element '"+element.getName()+"'");			
		}
	}
	
	/** @return the value of string attribute in element, otherwise throw {@link ReaderError} */
	public String getAttrString( IXMLElement element, String attr_name ) throws ReaderError
	{
		String v = element.getAttribute( attr_name, null );
		if( v!=null )  {
			return v;
		} else {
			throw new ReaderError("Missing attribute '"+attr_name+"' in element '"+element.getName()+"'");			
		}
	}
	
	/** @return the value of rectangle attribute in element, otherwise throw {@link ReaderError} */
	public Rectangle getAttrRectangle( IXMLElement element, String attr_name ) throws ReaderError
	{
		String v = element.getAttribute( attr_name, null );
		if( v!=null )  {
			Rectangle r = getAttr( element, attr_name, (Rectangle)null );
			if( r == null ) {
				throw new ReaderError("Invalid Rectangle attribute '"+attr_name+"' in element '"+element.getName()+"'");
			}
			return r;
		} else {
			throw new ReaderError("Missing attribute '"+attr_name+"' in element '"+element.getName()+"'");			
		}
	}
	
	/** @return the value of point attribute in element, otherwise throw {@link ReaderError} */
	public Point getAttrPoint( IXMLElement element, String attr_name ) throws ReaderError
	{
		String v = element.getAttribute( attr_name, null );
		if( v!=null )  {
			Point p = getAttr( element, attr_name, (Point)null );
			if( p == null ) {
				throw new ReaderError("Invalid Point attribute '"+attr_name+"' in element '"+element.getName()+"'");
			}
			return p;
		} else {
			throw new ReaderError("Missing attribute '"+attr_name+"' in element '"+element.getName()+"'");			
		}
	}
	
	
//TODO: the following mathod must be modified Element => IXMLElement	
	
	public boolean getAttr( IXMLElement element, String attr_name, boolean default_value )
	{
		String v = element.getAttribute( attr_name, null );
		if( v==null || v.isEmpty() ) return default_value;
		if( Boolean.TRUE.toString().equals( v ) ) return true;
		if( Boolean.FALSE.toString().equals( v ) ) return false;
		return default_value;
	}
	
	public float getAttr( IXMLElement element, String attr_name, float default_value )
	{
		String v = element.getAttribute( attr_name, null );
		if( v==null || v.isEmpty() ) return default_value;
		try {
			float value = Float.parseFloat( v );
			return value;
		} catch( NumberFormatException x ) {
			return default_value;
		}
	}
	
	public int getAttr( IXMLElement element, String attr_name, int default_value )
	{
		String v = element.getAttribute( attr_name, null );
		if( v==null || v.isEmpty() ) return default_value;
		try {
			int value = Integer.parseInt( v );
			return value;
		} catch( NumberFormatException x ) {
			return default_value;
		}
	}
	
	public String getAttr( IXMLElement element, String attr_name, String default_value )
	{
		String v = element.getAttribute( attr_name, null );
		if( v==null || v.isEmpty() ) return default_value;
		return v;
	}
	
	public RGB getAttr( IXMLElement element, String attr_name, RGB default_value ) 
	{
		String v = element.getAttribute( attr_name, null );
		if( v==null ) return default_value;
		String s[] = v.split(":"); //$NON-NLS-1$
		if( s.length!=3 ) return default_value;
		try {
			int r = Integer.parseInt( s[0] );
			int g = Integer.parseInt( s[1] );
			int b = Integer.parseInt( s[2] );
			return new RGB( r, g, b );
		} catch( NumberFormatException x ) {
			return default_value;
		}
	}
	
	public Rectangle getAttr( IXMLElement element, String attr_name, Rectangle default_value ) 
	{
		String v = element.getAttribute( attr_name, null );
		if( v==null ) return default_value;
		String s[] = v.split(":"); //$NON-NLS-1$
		if( s.length!=4 ) return default_value;
		try {
			int x = Integer.parseInt( s[0] );
			int y = Integer.parseInt( s[1] );
			int w = Integer.parseInt( s[2] );
			int h = Integer.parseInt( s[3] );
			return new Rectangle( x, y, w, h );
		} catch( NumberFormatException x ) {
			return default_value;
		}
	}
	
	public Point getAttr( IXMLElement element, String attr_name, Point default_value ) 
	{
		String v = element.getAttribute( attr_name, null );
		if( v==null ) return default_value;
		String s[] = v.split(":"); //$NON-NLS-1$
		if( s.length!=2 ) return default_value;
		try {
			int x = Integer.parseInt( s[0] );
			int y = Integer.parseInt( s[1] );
			return new Point( x, y );
		} catch( NumberFormatException x ) {
			return default_value;
		}
	}

}
